//
//  GPSObserver.m
//  Do Not Disturb
//
//  Created by Chris Karr on 9/2/07.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "GPSObserver.h"
#import "DNDDefines.h"
#include <termios.h>

#define BUFFER_SIZE 4096

@implementation GPSObserver

- (void) scan
{
	NSMutableDictionary * dict = [NSMutableDictionary dictionary];
	[dict setValue:[NSDate date] forKey:@"date"];

	if ([position valueForKey:@"Latitude"] != nil)
	{
		[dict setValue:[NSString stringWithFormat:@"Location: (%@, %@) [%@]", [position valueForKey:@"Latitude"], 
			[position valueForKey:@"Longitude"], [position valueForKey:@"State"]] forKey:@"name"];
	}
	else
		[dict setValue:@"Location: Unknown" forKey:@"name"];
	
	[[NSDistributedNotificationCenter defaultCenter] postNotificationName:DND_UPDATE object:@"GPSObserver" userInfo:dict];
}

- (GPSObserver *) init
{
	if (self = [super init])
	{
		position = [[NSMutableDictionary dictionary] retain];
		[NSThread detachNewThreadSelector:@selector(readThread:) toTarget:self withObject:position];
	}
		
	return self;
}

- (void) readThread:(NSMutableDictionary *) pd
{
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	char * deviceFilePath = "/dev/tty.KeySerial1";
		
	struct termios options;
 
	int fd = open (deviceFilePath, O_RDONLY | O_NONBLOCK);
	
	if (fd == -1)
		return;
		
	tcgetattr(fd, &options);

	memset(&options, 0, sizeof(struct termios));
	cfmakeraw(&options);
	cfsetspeed(&options, 4800);
	options.c_cflag = CREAD | CLOCAL;
	options.c_cflag |= CS8;
	tcsetattr(fd, TCSANOW, &options);
				
	int modem = 0;
				
	ioctl(fd, TIOCMGET, &modem);
	modem |= TIOCM_DTR;
	ioctl(fd, TIOCMSET, &modem);        
	
	unsigned char buff[BUFFER_SIZE];

	sleep (1);
	
	int k = 0;
	
	struct timeval timeOut;
	memset (&timeOut, 0, sizeof (struct timeval));
	timeOut.tv_sec = 1;

	// sleep (1);

	fd_set readSet;
	
	FD_ZERO (&readSet);
	FD_SET(fd, &readSet);
	
	NSMutableData * data = [[NSMutableData alloc] init];
	
	do
	{
		select (fd + 1, &readSet, NULL, NULL,&timeOut);
		k = read (fd, buff, BUFFER_SIZE);

		if (k != -1)
		{
			[data appendBytes:buff length:k];
			
			/* unsigned i = 0;
						
			for (i = 0; i < k; i++)
				printf("%c", buff[i]); */
			
			NSString * dataString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
			
			NSArray * lines = [dataString componentsSeparatedByString:@"\n"];
			
			int i = 0;
			for (i = 0; i < [lines count] - 1; i++)
			{
				NSString * line = [lines objectAtIndex:i];
				
				if ([line hasPrefix:@"$GPGLL"])
				{
					// NSLog (@"line = %@", line);
				
					NSArray * fields = [line componentsSeparatedByString:@","];
						
					NSString * latitude = [NSString stringWithFormat:@"%@ %@", [fields objectAtIndex:1], [fields objectAtIndex:2]];
					NSString * longitude = [NSString stringWithFormat:@"%@ %@", [fields objectAtIndex:3], [fields objectAtIndex:4]];
					NSString * date = [fields objectAtIndex:5];
					NSString * state = [fields objectAtIndex:6];

					[pd setValue:latitude forKey:@"Latitude"];
					[pd setValue:longitude forKey:@"Longitude"];
					[pd setValue:date forKey:@"Date"];
					[pd setValue:state forKey:@"State"];
				}
			}
			
			if ([lines count] > 0)
			{
				NSString * lastLine = [lines objectAtIndex:[lines count] - 1];
				
				[data setData:[NSData dataWithBytes:[lastLine cStringUsingEncoding:NSASCIIStringEncoding] length:[lastLine length]]];
			}
		}
		else if (errno == EAGAIN)
			k = 0;
		else
			NSLog (@"error = %d (%s)", errno, strerror (errno));
	}
	while (k != -1);
	
	close (fd);
	
	[data release];
	
	[pool release];
}

- (NSString *) getName
{
	return @"GPS";
}

@end
